from django.core.exceptions import ValidationError
from django.utils import timezone
from django.db import transaction

from app.models import (
    FranchiseApplication, 
    User, MerchantInfo
)
from middleware.util import make_response


class FranchiseService:
    @staticmethod
    def submit_application(user_id, shop_name, location, contact_info, business_hours, introduction=None):
        """
        提交加盟申请
        :param user_id: 申请用户的 UUID
        :param shop_name: 商家名称
        :param location: 地址
        :param contact_info: 联系方式
        :param business_hours: 营业时间
        :param introduction: 商家介绍
        :return: 申请结果
        """
        try:
            # 1. 获取用户并校验角色
            user = User.objects.get(id=user_id)
            if user.role != 'customer':
                raise ValidationError("只有普通用户可以申请加盟")

            # 2. 检查是否已经是商家
            if MerchantInfo.objects.filter(merchant_id=user_id).exists():
                raise ValidationError("您已经是商家，无需重复申请")

            # 3. 检查是否有待审批的申请
            if FranchiseApplication.objects.filter(
                applicant=user, 
                status='pending'
            ).exists():
                raise ValidationError("您已有待审批的申请，请等待审批结果")

            # 4. 验证商家名称是否已存在
            if MerchantInfo.objects.filter(shop_name=shop_name).exists():
                raise ValidationError("该商家名称已被注册")
            
            if FranchiseApplication.objects.filter(
                shop_name=shop_name,
                status__in=['pending', 'approved']
            ).exists():
                raise ValidationError("该商家名称已被申请或注册")

            # 5. 创建加盟申请
            application = FranchiseApplication.objects.create(
                applicant=user,
                shop_name=shop_name,
                location=location,
                contact_info=contact_info,
                business_hours=business_hours,
                introduction=introduction,
                status='pending'
            )

            return make_response(
                code=201,
                message="加盟申请提交成功",
                data={
                    "application_id": str(application.application_id),
                    "shop_name": application.shop_name,
                    "status": application.status
                }
            )

        except User.DoesNotExist:
            raise ValidationError("用户不存在")
        except Exception as e:
            raise ValidationError(f"申请提交失败：{str(e)}")

    @staticmethod
    def list_applications():
        """
        获取所有加盟申请列表（管理员用）
        :return: 申请列表
        """
        applications = FranchiseApplication.objects.select_related('applicant').all().order_by('-created_at')

        result = []
        for app in applications:
            result.append({
                "application_id": str(app.application_id),
                "applicant_name": app.applicant.username,
                "shop_name": app.shop_name,
                "location": app.location,
                "contact_info": app.contact_info,
                "business_hours": app.business_hours,
                "introduction": app.introduction,
                "status": app.status,
                "created_at": app.created_at.isoformat() if app.created_at else None,
                "approval_time": app.approval_time.isoformat() if app.approval_time else None,
                "approval_notes": app.approval_notes
            })

        return make_response(
            code=200,
            message="获取成功",
            data=result
        )

    @staticmethod
    def approve_application(application_id, action, notes=None):
        """
        审批加盟申请
        :param application_id: 申请 ID
        :param action: 审批动作 ('approve' 或 'reject')
        :param notes: 审批备注
        :return: 审批结果
        """
        try:
            application = FranchiseApplication.objects.select_related('applicant').get(
                application_id=application_id
            )
        except FranchiseApplication.DoesNotExist:
            raise ValidationError("申请不存在")

        if application.status != 'pending':
            raise ValidationError("该申请已被处理，无法重复审批")

        with transaction.atomic():
            merchant_id = None
            
            if action == 'approve':
                # 审批通过，创建商家记录
                # 再次检查商家名称是否被占用（防止并发问题）
                if MerchantInfo.objects.filter(shop_name=application.shop_name).exists():
                    raise ValidationError("该商家名称已被注册，审批失败")

                # 创建商家信息
                merchant = MerchantInfo.objects.create(
                    merchant_id=application.applicant.id,
                    shop_name=application.shop_name,
                    location=application.location,
                    contact_info=application.contact_info,
                    business_hours=application.business_hours,
                    introduction=application.introduction,
                    register_time=application.applicant.created_at
                )

                # 更新用户角色为商家
                user = application.applicant
                user.role = 'merchant'
                user.save()

                merchant_id = str(merchant.merchant_id)
                application.status = 'approved'

            elif action == 'reject':
                application.status = 'rejected'

            # 更新申请状态
            application.approval_time = timezone.now()
            application.approval_notes = notes
            application.save()

            return make_response(
                code=200,
                message=f"申请已{'通过' if action == 'approve' else '拒绝'}",
                data={
                    "application_id": str(application.application_id),
                    "status": application.status,
                    "merchant_id": merchant_id
                }
            )


    @staticmethod
    def get_my_applications(user_id):
        """
        获取用户自己的加盟申请
        :param user_id: 用户 ID
        :return: 申请列表
        """
        try:
            user = User.objects.get(id=user_id)
        except User.DoesNotExist:
            raise ValidationError("用户不存在")

        applications = FranchiseApplication.objects.filter(
            applicant=user
        ).order_by('-created_at')

        result = []
        for app in applications:
            result.append({
                "application_id": str(app.application_id),
                "shop_name": app.shop_name,
                "location": app.location,
                "contact_info": app.contact_info,
                "business_hours": app.business_hours,
                "introduction": app.introduction,
                "status": app.status,
                "created_at": app.created_at.isoformat() if app.created_at else None,
                "approval_time": app.approval_time.isoformat() if app.approval_time else None,
                "approval_notes": app.approval_notes
            })

        return make_response(
            code=200,
            message="获取成功",
            data=result 
        )